#ifndef     __CMD_CAN_H
#define     __CMD_CAN_H

#include "../utils/object.h"
#include "../utils/nocopyable.h"
#include "../conn/can_receiver.h"
#include "../conn/conn_write_helper.h"
#include <stdarg.h>

namespace pub_driver {

class CmdCAN : public Object<CmdCAN>, private NoCopyable, public ConnWriteHelper<CmdCAN> {

public:
    static constexpr uint32_t WRITE_BUF_SIZE = 128;

    void init();

    void write(const uint8_t *buf, usize_t len);

    template <uint8_t TYPE, typename... Ts>
    void write(uint8_t dst, Ts&&... ts) {
        wait_write_finish();
        usize_t len = conn::make_any<TYPE>(m_write_buf, dst, std::forward<Ts>(ts)...);
        write_raw(m_write_buf, len);
    }

    void log(const char *format, va_list ap);

#ifdef CAN_RECV_IPC
    conn::CANReceiver<50, 256> ipcReceiver;
#endif

#ifdef CAN_RECV_CARGO
    conn::CANReceiver<50, 256> cargoReceiver;
#endif

#ifdef CAN_RECV_HEAT
    conn::CANReceiver<50, 256> heatReceiver;
#endif

#ifdef CAN_RECV_PEARL
    conn::CANReceiver<50, 256> pearlReceiver;
#endif

#ifdef CAN_RECV_ICE
    conn::CANReceiver<50, 256> iceReceiver;
#endif

private:
    void write_raw(const uint8_t *buf, usize_t len);
    void wait_write_finish();

    uint8_t m_write_buf[WRITE_BUF_SIZE];
};

extern CmdCAN cmdCAN;

}



#endif
